package com.yance.fim.core.packets;

import com.yance.fim.core.enums.Code;
import com.yance.fim.core.enums.Command;

import java.nio.ByteBuffer;

/**
 * @author yance
 */
public class FimHeader {

    public static final int LENGTH = 10;
    public static final int VERSION = 2;
    public static final byte magic = (byte)0xf8;


    protected byte[] mContents;

    public FimHeader() {
        mContents = new byte[LENGTH];
        //flag
        mContents[0] = (byte)0xf8;
        //version
        mContents[1] = VERSION;
    }

    public FimHeader(ByteBuffer buffer) {
        mContents = new byte[LENGTH];
        if(buffer.limit() >= LENGTH) {
            for(int i = 0; i < LENGTH; i++) {
                mContents[i] = buffer.get();
            }
        }
    }

    public byte[] getContents() {
        return mContents;
    }

    public FimHeader setVersion(int version) {
        mContents[1] = (byte) version;
        return this;
    }

    public int getVersion() {
        return mContents[1];
    }

    public FimHeader setCommand(Command signal) {
        mContents[2] = (byte)((mContents[2] & (0x01 << 7)) | signal.ordinal());
        return this;
    }

    public Command getCommand() {
        return Command.toEnum((~(0x01 << 7)) & mContents[2]);
    }

    public FimHeader setLength(int length) {
        mContents[3] = (byte)((length >> 24) & 0xff);
        mContents[4] = (byte)((length >> 16) & 0xff);
        mContents[5] = (byte)((length >> 8)  & 0xff);
        mContents[6] = (byte)(length);
        return this;
    }

    public int getLength() {
        return ( ((mContents[3] & 0xff) << 24)
                |((mContents[4] & 0xff) << 16)
                |((mContents[5] & 0xff) << 8)
                | (0xff & mContents[6]));
    }

    public FimHeader setCode(Code code){
        mContents[7] = (byte)((mContents[7] & (0x01 << 7)) | code.ordinal()) ;
        return this;
    }

    public Code getCode(){
        return Code.toEnum((~(0x01 << 7)) & mContents[7]);
    }

    public FimHeader setMessageId(int messageId){
        mContents[8] = (byte)((messageId >> 8) & 0xff);
        mContents[9] = (byte)(messageId & 0xff);
        return this;
    }

    public int getMessageId(){
        return (((mContents[8] & 0xff) << 8) | (0xff & mContents[9]));
    }


    public boolean isValid(){
        return mContents[0] == (byte)0xf8 &&
                getLength() >= 0 &&
                getCommand() != Command.NONE;
    }
}
